#include <mission.hpp>
#include <mission_run.hpp>

static MissionRun* s_MissionRun = nullptr;

MissionRun* MissionRun::Instance()
{
	if (s_MissionRun == nullptr)
	{
		s_MissionRun = new MissionRun();
	}
	return s_MissionRun;
}

MissionRun::MissionRun()
	: TaskRun(PRIORITY_MISSION, 6000, "mission")
	, m_SemRw(1)
	, m_SeqId(0)
{
}

MissionRun::~MissionRun()
{
}

int MissionRun::Create(MissionList* missionList)
{
	if (missionList == nullptr)
	{
		return -1;
	}

	m_SemRw.Wait();
	missionList->SetMisId(++m_SeqId);
	m_MisMap[m_SeqId] = missionList;
	m_SemRw.Post();

	return m_SeqId;
}

void MissionRun::Abort(int id)
{
	MissionList* missionList = m_MisMap[id];
	if (missionList == nullptr)
	{
		return;
	}

	m_SemRw.Wait();

	missionList->Clear();
	delete missionList;
	m_MisMap.erase(id);

	m_SemRw.Post();
}

void MissionRun::Run(void* arg)
{
	uint32_t ms = 100;

	while (1)
	{
		m_SemRw.Wait();

		// 需要从map中移除的任务队列id
		std::vector<int> delIds;
		// 遍历map中所有任务队列
		for (const auto& pair : m_MisMap)
		{
			int misId				 = pair.first;
			MissionList* missionList = pair.second;

			// 当前任务队列是空表示任务队列中全部任务都已经完成
			if (missionList->IsEmpty())
			{
				delIds.push_back(misId);
				delete missionList;
				continue;
			}

			// 得到当前任务
			Mission* mission = missionList->Front();

			// 执行函数周期运行
			if (mission->m_State == MIS_STATE_RUNNING)
			{
				// 执行函数
				mission->RunImplNormal(mission->m_ArgNormal);
				// 扣除时间流失
				mission->m_TimeoutMs -= ms;
				// 如果超时
				if (mission->m_TimeoutMs <= 0)
				{
					// 设置为超时状态
					mission->m_State = MIS_STATE_TIMEOUT;
				}
			}
			// 任务暂停
			else if (mission->m_State == MIS_STATE_PAUSE)
			{
				// 不需要做什么
			}
			// 任务完成
			else if (mission->m_State == MIS_STATE_FINISHED)
			{
				mission->RunImplStopped(mission->m_ArgStopped);
				missionList->Pop();
				delete mission;
			}
			// 任务超时
			else if (mission->m_State == MIS_STATE_TIMEOUT)
			{
				mission->RunImplTimeout(mission->m_ArgTimeout);

				if (mission->m_TimeoutOpt == MIS_STOP_ALL)
				{
					missionList->Clear();
					delete missionList;
					delIds.push_back(misId);
					continue;
				}
				else if (mission->m_TimeoutOpt == MIS_STOP_CURRENT)
				{
					// 删除任务队列中的当前任务，并在下一个周期执行下一个任务
					missionList->Pop();
					delete mission;
				}
			}
			// 任务中止
			else if (mission->m_State == MIS_STATE_ABORTED)
			{
				// 清空任务队列
				missionList->Clear();
				delete missionList;
				delIds.push_back(misId);
				continue;
			}
		}

		// 从map中移除已经完成的任务队列
		for (const auto& e : delIds)
		{
			m_MisMap.erase(e);
		}

		m_SemRw.Post();

		TaskRun::mSleep(ms);
	}
}
